package com.pk.platform.business.charge.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.pk.platform.business.charge.dao.ITuitionDao;
import com.pk.platform.business.charge.dao.ITuitionDetailDao;
import com.pk.platform.business.charge.service.IChargeIndexService;
import com.pk.platform.business.charge.service.ITuitionService;
import com.pk.platform.business.charge.vo.TuitionVO;
import com.pk.platform.business.data.service.IBaseDataService;
import com.pk.platform.domain.charge.ChargeIndex;
import com.pk.platform.domain.charge.Tuition;
import com.pk.platform.domain.charge.TuitionDetail;
import com.pk.platform.domain.common.Kindergarten;
import com.pk.platform.domain.data.BaseData;
import com.pk.platform.domain.stock.StockObj;
import com.pk.platform.util.DateConverter;
import com.pk.platform.util.SelectOption;
import com.pk.platform.util.StringConverter;
import com.pk.platform.util.constant.ChargeConstant;
import com.pk.platform.util.constant.Constant;
import com.pk.platform.util.page.ListPage;
import com.pk.platform.util.page.Pager;

public class TuitionServiceImpl implements ITuitionService {

	private ITuitionDao tuitionDao;
	
	private ITuitionDetailDao tuitionDetailDao;
	
	private IChargeIndexService chargeIndexService;
	
	private IBaseDataService baseDataService;
	
	public ListPage queryTuition(TuitionVO tvo, Pager pager) {
		return tuitionDao.queryTuition(tvo, pager);
	}
	
	public synchronized void addTuition(Tuition tuition, Kindergarten kg,
			String[] indexGroup, String[] amountGroup, String[] dateStartGroup,
			String[] dateEndGroup, String discount, String addType) throws Exception
	{
		String tuitionNo = this.getNextNoByKg(kg);
		tuition.setTuitionNo(tuitionNo);
		tuitionDao.add(tuition); //添加一笔交费
		if(ChargeConstant.ADD_TYPE_TEMP.equals(addType))
		{
			//模板交费明细
			this.addTuitionDetail(tuition, indexGroup, amountGroup,
					dateStartGroup, dateEndGroup, discount);
		}
		else if(ChargeConstant.ADD_TYPE_MANUAL.equals(addType))
		{
			//手动资费明细
			this.addTuitionDetailManual(tuition, indexGroup, amountGroup,
					dateStartGroup, dateEndGroup, discount);
		}
	}

	public void updateTuition(Tuition tuition)
	{
		Tuition t = tuitionDao.get(Tuition.class, tuition.getId());
		t.setRemark(tuition.getRemark());
		t.setRemarkOfOther(tuition.getRemarkOfOther());
		tuitionDetailDao.addOperateLog("修改交费" + t.getTuitionNo(), Constant.SUCCESSFUL, t.getKindergarten());
	}
	
	public void delTuition(String id)
	{
		Tuition t = this.queryTuitionById(id);
		tuitionDetailDao.addOperateLog("删除交费" + t.getTuitionNo(), Constant.SUCCESSFUL, t.getKindergarten());
		t.setIsDel(Constant.Y_INT);
		//同时删除明细
		Set<TuitionDetail> tdSet = t.getTdSet();
		for(TuitionDetail td : tdSet)
		{
			td.setIsDel(Constant.Y_INT);
		}
	}
	
	public Tuition queryTuitionById(String id)
	{
		return tuitionDao.get(Tuition.class, id);
	}
	
	//追加费用
	public void superAddTuitionDetail(Tuition tuition, String[] indexGroup,
			String[] amountGroup, String[] dateStartGroup,
			String[] dateEndGroup, String discount, String addType) throws Exception
	{
		if(ChargeConstant.ADD_TYPE_TEMP.equals(addType))
		{
			//模板交费明细
			this.addTuitionDetail(tuition, indexGroup, amountGroup,
					dateStartGroup, dateEndGroup, discount);
		}
		else if(ChargeConstant.ADD_TYPE_MANUAL.equals(addType))
		{
			//手动资费明细
			this.addTuitionDetailManual(tuition, indexGroup, amountGroup,
					dateStartGroup, dateEndGroup, discount);
		}
		tuitionDao.getHibernateSession().flush();
		Double total = tuitionDetailDao.queryTotalAmount(tuition.getId());
		tuition.setTotalAmount(total);
	}
	
	public List<SelectOption> queryDiscountList()
	{
		List<BaseData> list = baseDataService.queryBaseDataByParentId(ChargeConstant.DISCOUNT);
		List<SelectOption> result = new ArrayList<SelectOption>();
		for(BaseData bd : list)
		{
			if("1".equals(bd.getDataValue()))
			{
				SelectOption so = new SelectOption(bd.getDataValue() + "", "全额");
				result.add(so);
			}
			else
			{
				String label = StringConverter.toNBitString(Double.parseDouble(bd.getDataValue()) * 10, 1) + "折";
				SelectOption so = new SelectOption(bd.getDataValue() + "", label);
				result.add(so);
			}
		}
		return result;
	}
	
	//下一单号
	private String getNextNoByKg(Kindergarten kg)
	{
		String kgCode = kg.getKgCode();
		int no = tuitionDao.getMaxNoByKgCode(kgCode);
		no += 1;
		String nextNo = StringConverter.fillZero(4, no+"");
		StringBuffer result = new StringBuffer();
		String date = DateConverter.dateToString(new Date(), DateConverter.FORMAT_SEVEN);
		result.append(kgCode).append("_").append(date).append("_").append(nextNo);
		return result.toString();
	}
	
	//模板添加交费明细
	private void addTuitionDetail(Tuition tuition,
			String[] indexGroup, String[] amountGroup, String[] dateStartGroup,
			String[] dateEndGroup, String discount) throws Exception
	{
		Double totalAmount = 0D;
		StringBuffer detailAmount = new StringBuffer();
		int len = indexGroup.length - 1; //-1是因为有一个作为添加的模板
		for(int i = 0; i < len; i++)
		{
			Double amount = Double.parseDouble(amountGroup[i]);
			if(amount == 0)
			{
				continue;
			}
			String yearStartx = dateStartGroup[i].split("-")[0];
			String yearEndx = dateEndGroup[i].split("-")[0];
			String monthStartx = dateStartGroup[i].split("-")[1];
			String monthEndx = dateEndGroup[i].split("-")[1];
			int yS = Integer.parseInt(yearStartx);
			int mS = Integer.parseInt(monthStartx);
			int yE = Integer.parseInt(yearEndx);
			int mE = Integer.parseInt(monthEndx);
			int endMonth = (yE * 12 + mE);
			int startMonth = (yS * 12 + mS);
			ChargeIndex ci = chargeIndexService.queryChargeIndexById(indexGroup[i]);
			for(int j = startMonth; j <= endMonth; j++)
			{
				TuitionDetail td = new TuitionDetail();
				int newYear = j / 12;
				int newMonth = j % 12;
				if(newMonth == 0)
				{
					newYear -= 1;
					newMonth = 12;
				}
				
				double dis = Double.parseDouble(discount);
				
				//减去库存货物
				Set<StockObj> stockObjSet = ci.getStockObjSet();
				for(StockObj so : stockObjSet)
				{
					if(tuition.getKindergarten().getId().equals(so.getKindergarten().getId()) && so.getIsDel() == 0)
					{
						double count = so.getStockCount();
						if(count < 1)
						{
							throw new Exception(ci.getIndexName() + "库存量不足，请进货。");
						}
						else
						{
							so.setStockCount(count - 1);
						}
						break;
					}
				}
				
				if(ChargeConstant.SCHOOLING.equals(ci.getIndexName()))
				{
					amount = amount * dis;
					td.setDiscount(discount);
				}
				else
				{
					td.setDiscount("1");
				}
				amount = StringConverter.toNBitNumber(amount, 0);
				td.setAmount(amount);
				td.setModifyAmount(td.getAmount() * ci.getModifyAmount()); //按百分比
				td.setYear(newYear + "");
				td.setMonth(StringConverter.fillZero(2, newMonth + ""));
				td.setTuitionDateStart(DateConverter.StringToDate(dateStartGroup[i], DateConverter.FORMAT_ONE));
				td.setTuitionDateEnd(DateConverter.StringToDate(dateEndGroup[i], DateConverter.FORMAT_ONE));
				td.setIsDel(Constant.N_INT);
				td.setTuition(tuition);
				td.setChargeIndex(ci);
				tuitionDao.add(td);
			}
			
			//写日志
			totalAmount += amount;
			detailAmount.append(ci.getIndexName()).append(StringConverter.toNBitString(amount, 0)).append("元");
			if(i < len - 1)
			{
				detailAmount.append("，");
			}
		}
		StringBuffer desc = new StringBuffer();
		desc.append("新增交费").append(tuition.getTuitionNo()).append("，").append("总金额为").append(StringConverter.toNBitString(totalAmount, 0)).append("元，");
		desc.append("其明细为").append(detailAmount.toString()).append("。");
		tuitionDetailDao.addOperateLog(desc.toString(), Constant.SUCCESSFUL, tuition.getKindergarten());
	}
	
	//手动添加交费明细
	private void addTuitionDetailManual(Tuition tuition,
			String[] indexGroup, String[] amountGroup, String[] dateStartGroup,
			String[] dateEndGroup, String discount) throws Exception
	{
		int len = indexGroup.length;
		for(int i = 0; i < len; i++)
		{
			Double amount = Double.parseDouble(amountGroup[i]);
			if(amount == 0)
			{
				continue;
			}
			TuitionDetail td = new TuitionDetail();
			String yearStartx = dateStartGroup[i].split("-")[0];
			String monthStartx = dateStartGroup[i].split("-")[1];
			double dis = Double.parseDouble(discount);
			ChargeIndex ci = chargeIndexService.queryChargeIndexById(indexGroup[i]);
			
			//减去库存货物
			Set<StockObj> stockObjSet = ci.getStockObjSet();
			for(StockObj so : stockObjSet)
			{
				if(tuition.getKindergarten().getId().equals(so.getKindergarten().getId()) && so.getIsDel() == 0)
				{
					double count = so.getStockCount();
					if(count < 1)
					{
						throw new Exception(ci.getIndexName() + "库存量不足，请进货。");
					}
					else
					{
						so.setStockCount(count - 1);
					}
					break;
				}
			}
			
			if(ChargeConstant.SCHOOLING.equals(ci.getIndexName()))
			{
				amount = amount * dis;
				td.setDiscount(discount);
			}
			else
			{
				td.setDiscount("1");
			}
			amount = StringConverter.toNBitNumber(amount, 0);
			td.setAmount(amount);
			td.setModifyAmount(td.getAmount() * ci.getModifyAmount()); //按百分比
			td.setYear(yearStartx);
			td.setMonth(monthStartx);
			td.setTuitionDateStart(DateConverter.StringToDate(dateStartGroup[i], DateConverter.FORMAT_ONE));
			td.setTuitionDateEnd(DateConverter.StringToDate(dateEndGroup[i], DateConverter.FORMAT_ONE));
			td.setIsDel(Constant.N_INT);
			td.setTuition(tuition);
			td.setChargeIndex(ci);
			tuitionDao.add(td);
		}
		tuitionDetailDao.addOperateLog("新增交费" + tuition.getTuitionNo(), Constant.SUCCESSFUL, tuition.getKindergarten());
	}
	
	public List<Map<String, Object>> getTitle(String tuitionId,int  isBj){
		return tuitionDao.getTitle(tuitionId, isBj);
	}

	public float getsubTotal(String tuitionId,int  isBj){
		return tuitionDao.getsubTotal(tuitionId, isBj);
	}
	
	public List<Map<String, Object>> getReportList(String tuitionId,int  isBj){
		return tuitionDao.getReportList(tuitionId, isBj);
	}
	public ITuitionDao getTuitionDao() {
		return tuitionDao;
	}

	public void setTuitionDao(ITuitionDao tuitionDao) {
		this.tuitionDao = tuitionDao;
	}

	public ITuitionDetailDao getTuitionDetailDao() {
		return tuitionDetailDao;
	}

	public void setTuitionDetailDao(ITuitionDetailDao tuitionDetailDao) {
		this.tuitionDetailDao = tuitionDetailDao;
	}

	public IChargeIndexService getChargeIndexService() {
		return chargeIndexService;
	}

	public void setChargeIndexService(IChargeIndexService chargeIndexService) {
		this.chargeIndexService = chargeIndexService;
	}

	public IBaseDataService getBaseDataService() {
		return baseDataService;
	}

	public void setBaseDataService(IBaseDataService baseDataService) {
		this.baseDataService = baseDataService;
	}

}
